package com.jie.gateway.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jie.common.constant.RedisKey;
import com.jie.common.constant.StrConst;
import com.jie.common.util.BaseParameterHolder;
import com.jie.common.util.TokenUtil;
import com.jie.component.exception.base.AuthenticationException;
import com.jie.component.exception.enums.AuthenticationError;
import com.jie.gateway.property.GatewayProperty;
import com.jie.model.redis.user.UserRedis;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

/**
 * @author jie
 * @version 1.0 2025-02-16
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TokenService {

    private final StringRedisTemplate stringRedisTemplate;

    private final GatewayProperty gatewayProperty;

    public String splitToken(String token) {
        if (token == null || token.isEmpty()) {
            return "";
        }
        // 使用replace方法去除"Bearer "
        return token.replace("Bearer ", "");
    }

    public boolean verifyToken(String token) {
        return TokenUtil.verifyToken(token);
    }

    public Long parseToken(String token) {
        return TokenUtil.getUserIdFromToken(token);
    }

    /**
     * 是否需要登录校验
     * @param url
     * @return
     */
    public boolean needLoginVerify(String url) {
        for (String checkTokenPath : gatewayProperty.getCheckTokenPaths()) {
            PathMatcher matcher = new AntPathMatcher();
            if (matcher.match(checkTokenPath, url)) {
                return true;
            }
        }
        return false;
    }

    public void doLoginVerify(String token, String url) {
        if (!needLoginVerify(url)) {
            return;
        }

        token = splitToken(token);

        if (!verifyToken(token)) {
            throw new AuthenticationException(AuthenticationError.TOKEN_ERROR);
        }

        Long userId = parseToken(token);
        if (userId == null) {
            throw new AuthenticationException(AuthenticationError.TOKEN_ERROR);
        }

        String loginUserKey = RedisKey.getRedisKey(RedisKey.LOGIN_USER_INFO + userId);
        String s = stringRedisTemplate.opsForValue().get(loginUserKey);
        if (StrUtil.isBlank(s)) {
            throw new AuthenticationException(AuthenticationError.UN_LOGIN_ERROR);
        }
        UserRedis bean = JSONUtil.toBean(s, UserRedis.class);

        if (!bean.getToken().equals(token)) {
            throw new AuthenticationException(AuthenticationError.LOGIN_EXPIRE);
        }

        BaseParameterHolder.setParameter(StrConst.USER_ID, userId.toString());
        log.info("登录的用户id {} 用户名 {}", bean.getId(), bean.getName());
    }
}
